﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using SPUploader.Core;

namespace SPUploader.UI
{
    public partial class Uploader : Form
    {
        #region Public Variables
        SPService _spService = new SPService();
        System.Threading.ManualResetEvent _busy = new System.Threading.ManualResetEvent(false);
        int _successCounter = 0;
        int _failCounter = 0;
        DateTime _startDate;
        DateTime _endDate;
        List<string> workspace = new List<string>();
        string _msg;
        string _filePath;
        #endregion

        #region Constructors
        public Uploader()
        {
            InitializeComponent();
        }
        #endregion

        #region System Tray
        private void UploadNotifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.Show();
            this.WindowState = FormWindowState.Normal;
        }

        private void showToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Show();
            this.WindowState = FormWindowState.Normal;
        }

        private void hideToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Hide();
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            bool cursorNotInBar = Screen.GetWorkingArea(this).Contains(Cursor.Position);

            if (this.WindowState == FormWindowState.Minimized && cursorNotInBar)
            {
                this.ShowInTaskbar = false;
                UploadNotifyIcon.Visible = true;
                this.Hide();
            }
        }
        #endregion

        #region Event Handlers
        private void Uploader_FormClosing(object sender, FormClosingEventArgs e)
        {
            PauseWorker();
            // Display a MsgBox asking the user to save changes or abort. 
            if (MessageBox.Show("Are you sure you want to exit?", "My Application",
                MessageBoxButtons.YesNo) == DialogResult.No)
            {
                // Cancel the Closing event from closing the form.
                e.Cancel = true;
            }
        }

        #region Settings Tab
        private void chkCustomCredential_CheckedChanged(object sender, EventArgs e)
        {
            txtUserName.Enabled = chkCustomCredential.Checked;
            txtPassword.Enabled = chkCustomCredential.Checked;
            txtDomain.Enabled = chkCustomCredential.Checked;
        }

        private void cmbDocumentLibrary_DropDown(object sender, EventArgs e)
        {

            _spService.SiteUrl = txtSpSiteUrl.Text;
            System.Net.ICredentials credentials;
            if (chkCustomCredential.Checked)
                credentials = new System.Net.NetworkCredential(_spService.UserName, _spService.Password, _spService.Domain);
            else
                credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
            cmbDocumentLibrary.DataSource = _spService.DocumentLibraryList(credentials);

        }
        #endregion

        #region Upload Tab
        private void btnStart_Click(object sender, EventArgs e)
        {
            
            _startDate = DateTime.Now;

            _spService.DocumentLibrary = cmbDocumentLibrary.SelectedItem.ToString();
            _spService.SiteUrl = txtSpSiteUrl.Text;

            this.btnStart.Enabled = false;
            progressBar1.Maximum = workspace.Count();
            progressBar1.Step = 1;
            progressBar1.Value = 0;
            lstViewer.Clear();

            this.lblStartsOn.Text = _startDate.ToString("dd/MM/yyyy  HH:mm:ss");

            if (!UploadBackgroundWorker.IsBusy)
            {
                lblStatus.Text = "Running...";
                if (workspace.Count != 0)
                {
                    UploadBackgroundWorker.RunWorkerAsync();
                    _busy.Set();
                    this.btnStart.Text = "Stop";
                }
                else
                {
                    lblStatus.Text = "Workspace is empty.";
                    this.btnStart.Enabled = true;
                }
            }
            else
            {
                this.btnStart.Text = "Start";
                lblStatus.Text = "Canceling...";
                UploadBackgroundWorker.CancelAsync();
            }
        }

        private void btnSelectPath_Click(object sender, EventArgs e)
        {
            using (FolderBrowserDialog fbd = new FolderBrowserDialog())
            {
                try
                {
                    fbd.SelectedPath = string.Empty;
                    fbd.ShowDialog();
                    if (fbd.SelectedPath != string.Empty)
                    {
                        //lstFilesToImport.Items.Clear();
                        txtFolderPath.Text = fbd.SelectedPath.ToString();

                        string[] filePaths = System.IO.Directory.GetFiles(@txtFolderPath.Text, "*.*",
                                             SearchOption.AllDirectories);
                        foreach (string name in filePaths)
                        {
                            workspace.Add(name);
                        }

                        lblTotal.Text = filePaths.Length.ToString();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }

            }
        }
        #endregion

        #endregion

        #region Upload Background Worker
        private void UploadBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            for (int i = 0; i <= progressBar1.Maximum; i++)
            {
                if (UploadBackgroundWorker.CancellationPending)
                {
                    // Pause for bit to demonstrate that there is time between 
                    // "Cancelling..." and "Canceled".
                    Thread.Sleep(1000);

                    // Set the e.Cancel flag so that the WorkerCompleted event
                    // knows that the process was canceled.
                    e.Cancel = true;
                    return;
                }

                if (i < workspace.Count())
                {
                    System.Net.ICredentials credentials;

                    if (chkCustomCredential.Checked)
                        credentials = new System.Net.NetworkCredential(_spService.UserName, _spService.Password, _spService.Domain);
                    else
                        credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
                    if (_spService.UploadFile(workspace[i].ToString(), credentials))
                    {
                        _filePath = workspace[i].ToString();
                        _msg = workspace[i].ToString() + "....Successfuly Uploaded!";
                        _successCounter += 1;
                    }
                    else
                    {
                        _filePath = workspace[i].ToString();
                        _msg = workspace[i].ToString() + "....Failed Uploading!";
                        _failCounter += 1;
                    }

                }

                UploadBackgroundWorker.ReportProgress(i);
                Thread.Sleep(10);
            }
        }

        private void UploadBackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // Change the value of the ProgressBar to the BackgroundWorker progress.
            progressBar1.Value = e.ProgressPercentage;
            // Set the text.
            this.Text = ((e.ProgressPercentage * 100) / progressBar1.Maximum).ToString() + "% SPUploader";
            TimeSpan timeSpent = DateTime.Now.Subtract(_startDate);
            this.lblDuration.Text = timeSpent.Days + " days, " + timeSpent.Hours + ":" + timeSpent.Minutes + ":" + timeSpent.Seconds;
            if ((((e.ProgressPercentage * 100) / progressBar1.Maximum)) != 100)
                lstViewer.AppendText(_msg);
            lblSuccessed.Text = _successCounter.ToString();
            lblFailed.Text = _failCounter.ToString();
            
            lblStatus.Text = "Uploading File : " + _filePath;
            lstViewer.AppendText(Environment.NewLine);
        }

        private void UploadBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            try
            {
                this.btnStart.Enabled = true;
                lblEndsOn.Text = DateTime.Now.ToString("dd/MM/yyyy  HH:mm:ss");
                _successCounter = 0;
                _failCounter = 0;
                workspace.Clear();
                progressBar1.Value = progressBar1.Maximum;
                // Check to see if an error occured in the 
                // background process.
                if (e.Error != null)
                {
                    MessageBox.Show(e.Error.Message);
                    return;
                }

                // Check to see if the background process was cancelled.
                if (e.Cancelled)
                {
                    lblStatus.Text = "Uploading Cancelled...";
                }
                else
                {
                    // Everything completed normally.
                    // process the response using e.Result

                    lblStatus.Text = "Uploading Completed...";
                    this.btnStart.Enabled = true;
                }
            }
            catch (Exception)
            {
                throw;
            }
        }     

        void ResumeWorker()
        {
            // Start the worker if it isn't running      
            if (!UploadBackgroundWorker.IsBusy)
                UploadBackgroundWorker.RunWorkerAsync();
            // Unblock the worker       
            _busy.Set();
        }
        void PauseWorker()
        {
            // Block the worker     
            _busy.Reset();
        }
        void CancelWorker()
        {
            if (UploadBackgroundWorker.IsBusy)
            {
                // Set CancellationPending property to true         
                UploadBackgroundWorker.CancelAsync();
                // Unblock worker so it can see that         
                _busy.Set();
            }
        }
        #endregion

        
    }
}
